package converter;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.io.*;
import persistance.Message;
import java.util.*;

public class UMLSequenceConversionManager {

	/*
	 * The ConversionManager class receives the data structure which holds the xml parsed tree.
	 * The ConversionManager class is invoked from the MainApplicationFrame.java class.  The ConversionManager class
	 * systematically iterates through the elements of the ArrayList containing the data which eventually constructs
	 * the sequence diagram.  By definition the life line nodes of the sequence diagram represent the agents from 
	 * the agent diagram.  The roles which belong to the agent are not displayed as part of the sequence diagram.
	 * The first task is to obtain a list of unique agents to determine how many agents exist.  Once this unified 
	 * list of agents is obtained for each agent, a lifeline node is created.  The second task is to iterate through
	 * the ArrayList and for each message there is a sender, receiver and the actually message itself.  For each 
	 * message the sender will have an activation bar created for it as well as the receiver will have an activation
	 * bar created for it.  Finally the third task is to create a connection where the contents of the message will be
	 * stored.  The connection will connect the two activation bars created for the sender and receiver. 
	 */
	
	private ArrayList<String> uniqueAgentList = new ArrayList<String>();
	
	
	public File createSequenceDiagram(ArrayList<Message>m,String fileName)
//	public void createSequenceDiagram(ArrayList<Message>m,String fileName)
	{
		//System.out.println("******************* in Conversion Manager ... ");
		
		uniqueAgentList = unifyAgents(m);
		violetSequenceDiagramCreator inst = new violetSequenceDiagramCreator();
		System.out.println("unified agent list has "+m.size()+" elements in it");	
		System.out.println(uniqueAgentList);
		
		Iterator i = uniqueAgentList.iterator();
		
		int iterationNumber = 0;
		
		// every agent must have a lifeline node created for it
		while(i.hasNext())
		{			
			//i.next() returns a generic object o of type "object"
			//each object o is equal to an element of the iterator
			Object o = i.next();
			
			//cast the object o to type string
			String agentName = (String)o;
			// create lifeline node for the agent			
			inst.addNode(agentName, iterationNumber);
			
			iterationNumber++;												
		}
		
		Iterator j = m.iterator();
		
		int messageNumber = 1;
		
		while(j.hasNext())
		{			
			//i.next() returns a generic object o of type "object"
			//each object o is equal to an element of the iterator
			Object o = j.next();
			
			//cast the object o to a message element
			Message message = (Message)o;
						
			inst.addParentActivationBar(messageNumber, uniqueAgentList.indexOf(message.get_child()),uniqueAgentList.indexOf(message.get_parent()));
			inst.addChildActivationBar(messageNumber, uniqueAgentList.indexOf(message.get_child()),uniqueAgentList.indexOf(message.get_parent()));
			inst.addConnection(message.get_name(), messageNumber);
			
			messageNumber++;												
		}
		
		
		inst.createSequenceDiagram(fileName);
		return new File(fileName); //Cheat:D
	}
	
	private ArrayList<String> unifyAgents(ArrayList<Message> m)
	{
		
		ArrayList<String>unifiedList = new ArrayList<String>();

		//create an iterator to iterate through the lovely array list of messages
		//can also do it with a for loop and it is cleaner, but this is more object oriented I guess
		//if done this way, then some casting will be needed 
		Iterator i = m.iterator();
		
		//LOOP THIS SHIT!!!
		while(i.hasNext())
		{			
			
			//i.next() returns a generic object o of type "object"
			//each object o is equal to an element of the iterator
			Object o = i.next();
			
			//cast the object o to a message element
			Message message = (Message)o;
			
			//now "message" is basically a line in the message structure. And all you
			//want is the child and parent. But make sure there are no duplicates			
			
			//If the message list DOES NOT contain the parent already, then add the parent
			if(!unifiedList.contains(message.get_parent()))
			{
				unifiedList.add(message.get_parent());	
			}		
			
			//If the message list DOES NOT contain the child already, then add the child
			if(!unifiedList.contains(message.get_child()))
			{
				unifiedList.add(message.get_child());	
			}
												
		}
		//print the unified list. There should be no duplicates
		System.out.println(unifiedList);
		
		//You can also sort the list if you want because in this case it is made up of just strings
		Collections.sort(unifiedList);
		
		//print the sorted unified list
		System.out.println(unifiedList);
		
		return unifiedList;
	}
	

	
}
